<template>
  <div>
    <h1>Watch情况3：监视【reactive】定义的【对象类型】数据</h1>
    <h2>姓名-{{ person.name }}</h2>
    <h2>年龄-{{ person.age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge" style="margin: 0 10px">修改年龄</button>
    <button @click="changeAll">修改全部信息</button>

    <hr />
    <div>
      <h1>Watch情况4：监视【reactive】or 【ref】定义的【某个属性】数据</h1>
      <h2>汽车名字-{{ car.carName }}</h2>
      <h2>汽车价格-{{ car.carPrice }}</h2>
      <h2>汽车配件-{{ car.carOther.oill }}、{{ car.carOther.quickly }}</h2>
      <button @click="changeCarName">修改汽车名字</button>
      <button @click="changeCarPrice" style="margin: 0 10px">
        修改汽车价格
      </button>
      <button @click="changeCarOther" style="margin: 0 5px">
        修改汽车配件
      </button>
      <button @click="changeCarOtherQuickly">修改汽车时速</button>
    </div>

    <div>
      <h1>Watch情况5：监视监视上述多个数据</h1>
    </div>
  </div>
</template>
<script setup lang="ts">
import { watch, reactive } from "vue";

let person = reactive({
  name: "风暴之女",
  age: 99,
});

let car = reactive({
  carName: "audi",
  carPrice: 100,
  carOther: {
    oill: 95,
    quickly: "100km/h",
  },
});

// Watch情况3：监视【reactive】定义的【对象类型】数据
function changeName() {
  person.name += "#";
}

function changeAge() {
  person.age += 1;
}

function changeAll() {
  Object.assign(person, { name: "深渊巨口", age: 10 });
}
/**
 * 当你监视的对象是用reactive定义的，这里默认开启的是深度监听模式，不管你的对象有多少层次的嵌套，并且这个deep深度监听还是不可以取消的，前提是reactive创建的对象，并且它新值和旧值都是一样的。这里的原因是因为它的地址根本没有发生变化，学过一点底层原理应该都会明白
 */
watch(person, (newData, oldData) => {
  console.log("person变化了", newData, oldData);
});

// Watch情况4：监视【reactive】or【ref】中的某个属性
function changeCarName() {
  car.carName += "!";
}
function changeCarPrice() {
  car.carPrice += 1;
}

function changeCarOther() {
  car.carOther = {
    oill: 97,
    quickly: "50km/h",
  };
}

function changeCarOtherQuickly() {
  car.carOther.quickly += "#";
}

// 4-1，监视响应式对象中的某个属性，且该属性是基本类型的，要写成函数形式
watch(
  () => car.carName,
  (newData, oldData) => {
    console.log("person变化了", newData, oldData);
  }
);

// 4-2，监视响应式对象中的某个属性，且该属性是对象类型的，可以直接写，也能写成函数，更推荐写成函数,当你是嵌套的时候，想监视更深层次的数据依然可以写deep
watch(
  () => car.carOther,
  (newData, oldData) => {
    console.log("汽车配件发生了变化", newData, oldData);
  },
  {
    deep: true,
  }
);

// Watch情况5：监视监视上述多个数据, 数组中要监视的对象写函数比较好
watch([() => person.name, () => car.carOther], (newData, oldData) => {
  console.log("汽车发生了变化", newData, oldData);
});
</script>

<style scoped></style>
